//
//  ChartCategoryDetailDateViewModel.swift
//  KoiAccounting
//
//  Created by 纪洪文 on 08.04.25.
//

import Foundation
class ChartCategoryDetailDateViewModel : KoiAccountingBaseViewModel {
    
    @Published var date: Date
    // 放在这里能比放在 view 里更持久
    @Published var category: AccountingCategory
    // 总金额
    @Published var totalAmount = 0.0
    // 平均值
    @Published var averageAmount = 0.0
    // 趋势数据
    @Published var trendData = [(day:String, amount:Double)]()
    // 类别金额汇总数据
    @Published var categoryDetailList = [AccountingDetailCombine]()
    
    @Published var orderBy = "date"
    
    // 数据仓库， 一些和数据相关的业务逻辑
    let detailRepo = DetailRepo()
    
    // 数据访问层，直接操作数据库
    let detailDao = KoiAccountingDB.standard.getDetailDao()
    
    init(date: Date, category: AccountingCategory) {
        self.date = date
        self.category = category
    }
    
    func loadData(dateType: DateSelectType) {
        switch dateType {
        case .week:
            loadWeekData(date: date, category: category)
        case .month:
            loadMonthData(date: date, category: category)
        case .year:
            loadYearData(date: date, category: category)
        }
    }
    
    private func loadWeekData(date: Date, category: AccountingCategory) {
        asyncBackground {
            let categoryType = category.getCategoryType()
            let cid = category.cid.orEmpty
            let weekDays = date.toWeekDays()
            // 获取周支出/收入总额
            let amountTotal = self.detailDao.getWeekTotalAmountByCid(weekDays: weekDays, categoryType: categoryType.rawValue, uid: self.uid, bookId: self.bookId, cid: cid)
            // 计算周平均值
            // 与今天比较
            let now = Date()
            // 一周7天
            var thisDay = 7
            if DateUtils.inThisWeek(weekDays: weekDays, date: now) {
                thisDay = now.dayOfWeek()
            }
            // 周平均值
            let amountAverage = amountTotal / Double(thisDay)
            // 获取趋势视图数据
            var trendData = [(day:String, amount:Double)]()
            let dayAmountMap = self.detailDao.getDayAmountByWeekDaysByCid(weekDays: weekDays, categoryType: categoryType.rawValue, uid: self.uid, bookId: self.bookId, cid: cid)
            weekDays.forEach { day in
                let showDay = DateUtils.weekdayAbbr(from: day) ?? ""
                if let dayAmount = dayAmountMap[day] {
                    trendData.append((day:showDay, amount:dayAmount))
                } else {
                    trendData.append((day:showDay, amount:0.0))
                }
            }
            // 获取类别统计数据
            let categoryDetailList = self.detailDao.getWeekDetailListByCid(weekDays: weekDays, cid: cid, uid: self.uid, bookId: self.bookId, orderBy: self.orderBy)
            
            self.asyncMain {
                self.totalAmount = amountTotal
                self.averageAmount = amountAverage
                self.trendData = trendData
                self.categoryDetailList = categoryDetailList
            }
        }
    }
    
    private func loadMonthData(date: Date, category: AccountingCategory) {
        asyncBackground {
            let categoryType = category.getCategoryType()
            let cid = category.cid.orEmpty
            let month = date.toYearMonth()
            // 获取支出/收入总额
            let amountTotal = self.detailDao.getMonthTotalAmountByCid(month: month, categoryType: categoryType.rawValue, uid: self.uid, bookId: self.bookId, cid: cid)
            // 计算平均值
            var thisDay = date.monthMaxDays()
            if DateUtils.inThisMonth(data: date) {
                thisDay = date.dayOfMonth()
            }
            // 平均值
            let amountAverage = amountTotal / Double(thisDay)
            // 获取趋势视图数据
            var trendData = [(day:String, amount:Double)]()
            let dayAmountMap = self.detailDao.getDayAmountByMonthByCid(month: month, categoryType: categoryType.rawValue, uid: self.uid, bookId: self.bookId, cid: cid)
            date.monthDays().forEach { day in
                let showDay = DateUtils.monthDayAbbr(from: day) ?? ""
                if let dayAmount = dayAmountMap[day] {
                    trendData.append((day:showDay, amount:dayAmount))
                } else {
                    trendData.append((day:showDay, amount:0.0))
                }
            }
            // 获取类别统计数据
            let categoryDetailList = self.detailDao.getMonthDetailListByCid(month: month, cid: cid, uid: self.uid, bookId: self.bookId, orderBy: self.orderBy)
            
            self.asyncMain {
                self.totalAmount = amountTotal
                self.averageAmount = amountAverage
                self.trendData = trendData
                self.categoryDetailList = categoryDetailList
            }
        }
    }
    
    private func loadYearData(date: Date, category: AccountingCategory) {
        asyncBackground {
            let categoryType = category.getCategoryType()
            let cid = category.cid.orEmpty
            let year = date.toYear()
            // 获取支出/收入总额
            let amountTotal = self.detailDao.getYearTotalAmountByCid(year: year, categoryType: categoryType.rawValue, uid: self.uid, bookId: self.bookId, cid: cid)
            // 计算平均值
            var thisDay = 12
            if DateUtils.inThisYear(data: date) {
                thisDay = date.monthOfYear()
            }
            // 周平均值
            let amountAverage = amountTotal / Double(thisDay)
            // 获取趋势视图数据
            var trendData = [(day:String, amount:Double)]()
            let dayAmountMap = self.detailDao.getDayAmountByYearByCid(year: year, categoryType: categoryType.rawValue, uid: self.uid, bookId: self.bookId, cid: cid)
            for (i, day) in date.yearMonths().enumerated() {
                let showDay = "\(i+1)"
                if let dayAmount = dayAmountMap[day] {
                    trendData.append((day:showDay, amount:dayAmount))
                } else {
                    trendData.append((day:showDay, amount:0.0))
                }
            }
            // 获取类别统计数据
            let categoryDetailList = self.detailDao.getYearDetailListByCid(year: year, cid: cid, uid: self.uid, bookId: self.bookId, orderBy: self.orderBy)
            
            self.asyncMain {
                self.totalAmount = amountTotal
                self.averageAmount = amountAverage
                self.trendData = trendData
                self.categoryDetailList = categoryDetailList
            }
        }
    }
}
